{-# LANGUAGE MultiParamTypeClasses #-}

module Main () where

{-
import Cyc

default ()

data WhiteKey = C | D | E | F | G | A | B
    deriving(Eq, Show, Bounded, Enum)

instance Cyc WhiteKey

instance MetricCyc Double WhiteKey where
    metric _ = [2,2,1,2,2,2,1]

m = (loopMetric D) :: Double

main :: IO ()
main = print (m)
-}






import Theory
import Utility
import Cyc (isarithm, metricTravel)
import Tests hiding (main)
import Test.QuickCheck (Property(..), quickCheck)
import Test.QuickCheck.Batch (run, runTests, TestOptions(..))


aNote = Note (PitchClass B Natural) (octave 3)
anotherNote = Note {
      oct = (octave 4)
    , pitchClass = PitchClass {
          accidental = Flat
        , whiteKey = D
        }
    }
c = chord [aNote, anotherNote]

o3 = octave 3
o4 = octave 4
o5 = octave 5
o6 = octave 6

test=[  halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass D Natural) o3) == -12,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass E Natural) o3) == -10,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass F Natural) o3) == -9,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass G Natural) o3) == -7,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass A Natural) o3) == -5,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass B Natural) o3) == -3,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass C Natural) o3) == -14,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass C Natural) o4) == -2,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass D Natural) o4) == 0,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass E Natural) o4) == 2,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass F Natural) o4) == 3,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass G Natural) o4) == 5,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass A Natural) o4) == 7,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass B Natural) o4) == 9,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass C Natural) o4) == -2,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass C Natural) o5) == 10,
    halfStepsAbove (Note (PitchClass D Natural) o4) (Note (PitchClass D Natural) o5) == 12,
    halfStepsAbove (Note (PitchClass E Natural) o4) (Note (PitchClass D Natural) o5) == 10,
    halfStepsAbove (Note (PitchClass F Natural) o4) (Note (PitchClass D Natural) o5) == 9,
    halfStepsAbove (Note (PitchClass G Natural) o4) (Note (PitchClass D Natural) o5) == 7,
    halfStepsAbove (Note (PitchClass A Natural) o4) (Note (PitchClass D Natural) o5) == 5,
    halfStepsAbove (Note (PitchClass B Natural) o4) (Note (PitchClass D Natural) o5) == 3,
    halfStepsAbove (Note (PitchClass C Natural) o4) (Note (PitchClass D Natural) o5) == 14,
    halfStepsAbove (Note (PitchClass C Natural) o5) (Note (PitchClass D Natural) o5) == 2,
    halfStepsAbove (Note (PitchClass D Natural) o5) (Note (PitchClass D Natural) o5) == 0,
    halfStepsAbove (Note (PitchClass E Natural) o5) (Note (PitchClass D Natural) o5) == -2,
    halfStepsAbove (Note (PitchClass F Natural) o5) (Note (PitchClass D Natural) o5) == -3,
    halfStepsAbove (Note (PitchClass G Natural) o5) (Note (PitchClass D Natural) o5) == -5,
    halfStepsAbove (Note (PitchClass A Natural) o5) (Note (PitchClass D Natural) o5) == -7,
    halfStepsAbove (Note (PitchClass B Natural) o5) (Note (PitchClass D Natural) o5) == -9,
    halfStepsAbove (Note (PitchClass C Natural) o6) (Note (PitchClass D Natural) o5) == -10,
    halfStepsAbove (Note (PitchClass D Natural) o6) (Note (PitchClass D Natural) o5) == -12,
    halfStepsAbove (Note (PitchClass E Natural) o6) (Note (PitchClass D Natural) o5) == -14]



main :: IO ()
main = do
    print (100::Note)
    print (aNote, anotherNote, midiNums c, halfStepSeq c, freqs c)
    print $ zip test [1..(length test)]
    print $ and test
    print $ L $ map (\x -> let Just (n,y) = metricTravel x $ PitchClass B Natural in (n,isarithm (0::Int) y)) ([-32..32]::[Int])

    print $ metricTravel (-36::Int) $ PitchClass F Sharp

    runTests "simple" options
        [ run (prop_m1 :: [Integer] -> Property)
        , run (prop_m2 :: [Integer] -> Property)
        , run (prop_m3 :: [Integer] -> Property)
        , run (prop_m4 :: [Integer] -> Property)

        , run (prop_s :: WhiteKey -> Bool)
        , run (prop_s :: Accidental -> Bool)
        , run (prop_s :: Note -> Bool)
--      , run (prop_s :: Octave -> Bool)
--      , run (prop_s :: MidiNum -> Bool)
        , run (prop_s :: PitchClass -> Bool)

        -- Steppable additive inverse
        , run (prop_f :: WhiteKey -> WhiteKey -> Bool)
        , run (prop_f :: Accidental -> Accidental -> Bool)
        , run (prop_f :: Note -> Note -> Bool)
--      , run (prop_f :: Octave -> Octave -> Bool)
--      , run (prop_f :: MidiNum -> MidiNum -> Bool)
        , run (prop_f :: PitchClass -> PitchClass -> Bool)

        , run (prop_mt1 :: WhiteKey -> Int -> Bool)
        , run (prop_mt1 :: PitchClass -> Int -> Bool)
        , run (prop_mt2 :: Int -> WhiteKey -> Bool)
        , run (prop_mt2 :: Int -> PitchClass -> Bool) -- failing to satisfy that just traveling an integer number of loops gives that number of loops
        , run (prop_mt3 :: Int -> WhiteKey -> Bool)
        , run (prop_mt3 :: Int -> PitchClass -> Bool)
        ]

{-
    print (0::Note)
    print (1::Note)


    print ((fromIntegral (-1))::Note)
    print (negate 1)
    print ((negate 1)::Note)

--    print ((-1)::Note)

    -- why does this work, when (-1)::Note loops?
    print $ Note newp (o + octs)
        where (m, Note {pitchClass = p, oct = o}) = midiNumRef
              Just (octs, newp)                   = metricTravel ugh p -- assume we can travel exactly any integral distance -- maybe make a predicate on MetricCyc to test this...  (just that all enums up to loopMetric available)
              ugh                                 = ((fromIntegral x) - (fromIntegral m))::Int
              x = -1
-}



--
--    print $ (Octave 3) - 5
--    print (newp, ugh)
--        where
--        (m, Note {pitchClass = p, oct = o}) = midiNumRef
--        Just (octs, newp)                   = metricTravel (-4::Int) p
--        ugh = ((fromIntegral (-4)) - (fromIntegral m))::Int
--




    print $ L $ ([-40..(-30)]::[Note])


{-
test=[  halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass D Natural) 3) == -12,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass E Natural) 3) == -10,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass F Natural) 3) == -9,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass G Natural) 3) == -7,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass A Natural) 3) == -5,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass B Natural) 3) == -3,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass C Natural) 3) == -14,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass C Natural) 4) == -2,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass D Natural) 4) == 0,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass E Natural) 4) == 2,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass F Natural) 4) == 3,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass G Natural) 4) == 5,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass A Natural) 4) == 7,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass B Natural) 4) == 9,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass C Natural) 4) == -2,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass C Natural) 5) == 10,
    halfStepsAbove (Note (PitchClass D Natural) 4) (Note (PitchClass D Natural) 5) == 12,
    halfStepsAbove (Note (PitchClass E Natural) 4) (Note (PitchClass D Natural) 5) == 10,
    halfStepsAbove (Note (PitchClass F Natural) 4) (Note (PitchClass D Natural) 5) == 9,
    halfStepsAbove (Note (PitchClass G Natural) 4) (Note (PitchClass D Natural) 5) == 7,
    halfStepsAbove (Note (PitchClass A Natural) 4) (Note (PitchClass D Natural) 5) == 5,
    halfStepsAbove (Note (PitchClass B Natural) 4) (Note (PitchClass D Natural) 5) == 3,
    halfStepsAbove (Note (PitchClass C Natural) 4) (Note (PitchClass D Natural) 5) == 14,
    halfStepsAbove (Note (PitchClass C Natural) 5) (Note (PitchClass D Natural) 5) == 2,
    halfStepsAbove (Note (PitchClass D Natural) 5) (Note (PitchClass D Natural) 5) == 0,
    halfStepsAbove (Note (PitchClass E Natural) 5) (Note (PitchClass D Natural) 5) == -2,
    halfStepsAbove (Note (PitchClass F Natural) 5) (Note (PitchClass D Natural) 5) == -3,
    halfStepsAbove (Note (PitchClass G Natural) 5) (Note (PitchClass D Natural) 5) == -5,
    halfStepsAbove (Note (PitchClass A Natural) 5) (Note (PitchClass D Natural) 5) == -7,
    halfStepsAbove (Note (PitchClass B Natural) 5) (Note (PitchClass D Natural) 5) == -9,
    halfStepsAbove (Note (PitchClass C Natural) 6) (Note (PitchClass D Natural) 5) == -10,
    halfStepsAbove (Note (PitchClass D Natural) 6) (Note (PitchClass D Natural) 5) == -12,
    halfStepsAbove (Note (PitchClass E Natural) 6) (Note (PitchClass D Natural) 5) == -14]
-}
